<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Markdown 转微信公众号文章编辑器</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            line-height: 1.6;
            color: #333;
            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
            min-height: 100vh;
            padding: 20px;
        }

        .container {
            max-width: 1400px;
            margin: 0 auto;
        }

        header {
            text-align: center;
            margin-bottom: 30px;
            padding: 20px;
            background: white;
            border-radius: 10px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            position: relative;
        }

        h1 {
            color: #2c3e50;
            margin-bottom: 10px;
        }

        .subtitle {
            color: #7f8c8d;
            font-size: 1.1rem;
        }

        /* 右上角按钮容器 */
        .header-controls {
            position: absolute;
            top: 20px;
            right: 20px;
            display: flex;
            gap: 10px;
        }

        .editor-container {
            display: flex;
            gap: 20px;
            margin-bottom: 20px;
            flex-wrap: wrap;
        }

        .panel {
            flex: 1;
            min-width: 300px;
            background: white;
            border-radius: 10px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            overflow: hidden;
            display: flex;
            flex-direction: column;
        }

        .panel-header {
            background: #3498db;
            color: white;
            padding: 15px 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .panel-header h2 {
            font-size: 1.2rem;
            margin: 0;
        }

        .panel-content {
            flex: 1;
            padding: 20px;
            overflow: auto;
        }

        #markdown-input {
            width: 100%;
            height: 100%;
            min-height: 500px;
            border: 1px solid #ddd;
            border-radius: 5px;
            padding: 15px;
            font-family: 'Courier New', monospace;
            font-size: 14px;
            resize: vertical;
        }

        #preview {
            min-height: 500px;
            padding: 20px;
            line-height: 1.8;
        }

        /* 按钮样式 */
        .btn {
            padding: 10px 20px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 14px;
            font-weight: 600;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .btn-primary {
            background: #2ecc71;
            color: white;
        }

        .btn-primary:hover {
            background: #27ae60;
            transform: translateY(-2px);
        }

        .btn-secondary {
            background: #3498db;
            color: white;
        }

        .btn-secondary:hover {
            background: #2980b9;
            transform: translateY(-2px);
        }

        .btn-danger {
            background: #e74c3c;
            color: white;
        }

        .btn-danger:hover {
            background: #c0392b;
            transform: translateY(-2px);
        }

        .upload-area {
            border: 2px dashed #3498db;
            border-radius: 10px;
            padding: 30px;
            text-align: center;
            margin-top: 20px;
            background: #f8fafc;
            cursor: pointer;
            transition: all 0.3s ease;
        }

        .upload-area:hover {
            background: #e8f4fc;
            border-color: #2980b9;
        }

        .upload-area i {
            font-size: 48px;
            color: #3498db;
            margin-bottom: 15px;
        }

        .upload-text {
            font-size: 18px;
            color: #3498db;
            margin-bottom: 10px;
        }

        .upload-hint {
            color: #7f8c8d;
            font-size: 14px;
        }

        #image-input {
            display: none;
        }

        .image-preview {
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
            margin-top: 20px;
        }

        .image-item {
            position: relative;
            width: 100px;
            height: 100px;
            border-radius: 5px;
            overflow: hidden;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        }

        .image-item img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }

        .image-item .delete {
            position: absolute;
            top: 5px;
            right: 5px;
            background: rgba(231, 76, 60, 0.8);
            color: white;
            border: none;
            border-radius: 50%;
            width: 24px;
            height: 24px;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            font-size: 12px;
        }

        .tips {
            background: #fff9e6;
            border-left: 4px solid #f1c40f;
            padding: 15px;
            margin-top: 20px;
            border-radius: 0 5px 5px 0;
        }

        .tips h3 {
            color: #f39c12;
            margin-bottom: 10px;
        }

        .tips ul {
            padding-left: 20px;
        }

        .tips li {
            margin-bottom: 5px;
        }

        /* 微信公众号文章样式 */
        .wechat-article {
            font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", sans-serif;
            line-height: 1.8;
            color: #333;
            max-width: 100%;
            word-wrap: break-word;
        }

        .wechat-article h1, 
        .wechat-article h2, 
        .wechat-article h3 {
            color: #2c3e50;
            margin: 25px 0 15px;
            font-weight: 600;
        }

        .wechat-article h1 {
            font-size: 22px;
            border-bottom: 1px solid #eee;
            padding-bottom: 10px;
        }

        .wechat-article h2 {
            font-size: 18px;
        }

        .wechat-article h3 {
            font-size: 16px;
        }

        .wechat-article p {
            margin-bottom: 15px;
            text-align: justify;
        }

        .wechat-article blockquote {
            border-left: 4px solid #3498db;
            background: #f8fafc;
            padding: 15px 20px;
            margin: 20px 0;
            border-radius: 0 5px 5px 0;
        }

        .wechat-article img {
            max-width: 100%;
            height: auto;
            display: block;
            margin: 20px auto;
            border-radius: 5px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        }

        .wechat-article ul, 
        .wechat-article ol {
            padding-left: 30px;
            margin-bottom: 15px;
        }

        .wechat-article li {
            margin-bottom: 8px;
        }

        .wechat-article code {
            background: #f8f8f8;
            padding: 2px 6px;
            border-radius: 3px;
            font-family: 'Courier New', monospace;
            color: #e74c3c;
        }

        .wechat-article pre {
            background: #2c3e50;
            color: #ecf0f1;
            padding: 15px;
            border-radius: 5px;
            overflow-x: auto;
            margin: 20px 0;
        }

        .wechat-article pre code {
            background: none;
            color: inherit;
            padding: 0;
        }

        .wechat-article table {
            width: 100%;
            border-collapse: collapse;
            margin: 20px 0;
        }

        .wechat-article th, 
        .wechat-article td {
            border: 1px solid #ddd;
            padding: 10px 15px;
            text-align: left;
        }

        .wechat-article th {
            background: #f5f7fa;
            font-weight: 600;
        }

        .wechat-article a {
            color: #3498db;
            text-decoration: none;
        }

        .wechat-article a:hover {
            text-decoration: underline;
        }

        @media (max-width: 768px) {
            .editor-container {
                flex-direction: column;
            }
            
            .panel {
                min-width: 100%;
            }

            .header-controls {
                position: static;
                justify-content: center;
                margin-top: 15px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1><i class="fas fa-file-alt"></i> Markdown 转微信公众号文章编辑器</h1>
            <p class="subtitle">支持图片上传、实时预览、一键复制到微信公众号</p>
            
            <!-- 右上角按钮组 -->
            <div class="header-controls">
                <button id="convert-btn" class="btn btn-primary">
                    <i class="fas fa-sync-alt"></i> 转换
                </button>
                <button id="copy-btn" class="btn btn-secondary">
                    <i class="fas fa-copy"></i> 复制
                </button>
                <button id="clear-btn" class="btn btn-danger">
                    <i class="fas fa-trash-alt"></i> 清空
                </button>
            </div>
        </header>

        <div class="editor-container">
            <div class="panel">
                <div class="panel-header">
                    <h2><i class="fas fa-edit"></i> Markdown 编辑器</h2>
                    <span class="word-count">字数: <span id="word-count">0</span></span>
                </div>
                <div class="panel-content">
                    <textarea id="markdown-input" placeholder="在这里输入您的 Markdown 内容..."># 欢迎使用 Markdown 编辑器

这是一篇示例文章，向您展示 Markdown 如何转换为微信公众号文章格式。

## 主要特性

- 支持图片上传和预览
- 实时转换和预览
- 微信公众号友好格式
- 代码高亮显示

### 代码示例

\`\`\`javascript
// 这是一个JavaScript代码示例
function helloWorld() {
    console.log("Hello, WeChat!");
    return "欢迎关注我们的公众号！";
}
\`\`\`

### 表格示例

| 功能 | 支持情况 | 说明 |
|------|----------|------|
| 图片 | ✅ 支持 | 可上传本地图片 |
| 代码高亮 | ✅ 支持 | 多种编程语言 |
| 数学公式 | ✅ 支持 | LaTeX 语法 |

> 提示：这是一个引用块，适合用于强调重要内容。

**加粗文本** 和 *斜体文本* 也都支持。

感谢使用本编辑器！</textarea>
                </div>
            </div>

            <div class="panel">
                <div class="panel-header">
                    <h2><i class="fas fa-eye"></i> 微信公众号预览</h2>
                    <span class="help"><i class="fas fa-question-circle"></i> 实时预览</span>
                </div>
                <div class="panel-content">
                    <div id="preview" class="wechat-article">
                        <p>预览将在这里显示...</p>
                    </div>
                </div>
            </div>
        </div>

        <div class="panel">
            <div class="panel-header">
                <h2><i class="fas fa-images"></i> 图片上传与管理</h2>
            </div>
            <div class="panel-content">
                <div class="upload-area" id="upload-area">
                    <i class="fas fa-cloud-upload-alt"></i>
                    <div class="upload-text">点击或拖拽图片到这里上传</div>
                    <div class="upload-hint">支持 JPG、PNG 格式，单张图片不超过 5MB</div>
                    <input type="file" id="image-input" accept="image/*" multiple>
                </div>
                
                <div class="image-preview" id="image-preview">
                    <!-- 上传的图片会在这里显示 -->
                </div>
            </div>
        </div>

        <div class="tips">
            <h3><i class="fas fa-lightbulb"></i> 使用提示</h3>
            <ul>
                <li>图片上传后会自动转换为 Base64 格式嵌入到文章中，确保在微信公众号中正常显示</li>
                <li>复制内容后，可以直接粘贴到微信公众号编辑器中</li>
                <li>支持标准的 Markdown 语法：标题、列表、代码块、表格等</li>
                <li>在手机上打开时，建议横屏使用以获得更好的编辑体验</li>
            </ul>
        </div>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/4.3.0/marked.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.0.3/purify.min.js"></script>
    <script>
        // 获取DOM元素
        const markdownInput = document.getElementById('markdown-input');
        const preview = document.getElementById('preview');
        const convertBtn = document.getElementById('convert-btn');
        const copyBtn = document.getElementById('copy-btn');
        const clearBtn = document.getElementById('clear-btn');
        const uploadArea = document.getElementById('upload-area');
        const imageInput = document.getElementById('image-input');
        const imagePreview = document.getElementById('image-preview');
        const wordCountElement = document.getElementById('word-count');

        // 配置 marked 选项
        marked.setOptions({
            breaks: true,
            gfm: true,
            highlight: function(code, lang) {
                // 简单的代码高亮实现
                return `<pre><code class="language-${lang}">${escapeHtml(code)}</code></pre>`;
            }
        });

        // HTML转义函数
        function escapeHtml(unsafe) {
            return unsafe
                .replace(/&/g, "&amp;")
                .replace(/</g, "&lt;")
                .replace(/>/g, "&gt;")
                .replace(/"/g, "&quot;")
                .replace(/'/g, "&#039;");
        }

        // 更新字数统计
        function updateWordCount() {
            const text = markdownInput.value;
            const count = text.replace(/\s/g, '').length;
            wordCountElement.textContent = count;
        }

        // 转换Markdown为HTML
        function convertMarkdown() {
            const markdownText = markdownInput.value;
            const rawHtml = marked.parse(markdownText);
            // 使用DOMPurify清理HTML，防止XSS攻击
            const cleanHtml = DOMPurify.sanitize(rawHtml);
            preview.innerHTML = cleanHtml;
        }

        // 复制内容到剪贴板
        function copyToClipboard() {
            const range = document.createRange();
            range.selectNode(preview);
            window.getSelection().removeAllRanges();
            window.getSelection().addRange(range);
            
            try {
                const successful = document.execCommand('copy');
                if (successful) {
                    // 显示复制成功提示
                    const originalText = copyBtn.innerHTML;
                    copyBtn.innerHTML = '<i class="fas fa-check"></i> 已复制';
                    copyBtn.style.background = '#2ecc71';
                    setTimeout(() => {
                        copyBtn.innerHTML = originalText;
                        copyBtn.style.background = '#3498db';
                    }, 2000);
                }
            } catch (err) {
                console.error('复制失败:', err);
                alert('复制失败，请手动选择内容复制');
            }
            
            window.getSelection().removeAllRanges();
        }

        // 清空内容
        function clearContent() {
            if (confirm('确定要清空所有内容吗？')) {
                markdownInput.value = '';
                preview.innerHTML = '<p>预览将在这里显示...</p>';
                imagePreview.innerHTML = '';
                updateWordCount();
            }
        }

        // 处理图片上传
        function handleImageUpload(files) {
            for (let file of files) {
                if (!file.type.match('image.*')) {
                    alert('请上传图片文件！');
                    continue;
                }
                
                if (file.size > 5 * 1024 * 1024) {
                    alert('图片大小不能超过5MB！');
                    continue;
                }
                
                const reader = new FileReader();
                reader.onload = function(e) {
                    const imageItem = document.createElement('div');
                    imageItem.className = 'image-item';
                    
                    const img = document.createElement('img');
                    img.src = e.target.result;
                    
                    const deleteBtn = document.createElement('button');
                    deleteBtn.className = 'delete';
                    deleteBtn.innerHTML = '<i class="fas fa-times"></i>';
                    deleteBtn.onclick = function() {
                        imagePreview.removeChild(imageItem);
                    };
                    
                    imageItem.appendChild(img);
                    imageItem.appendChild(deleteBtn);
                    imagePreview.appendChild(imageItem);
                    
                    // 生成Markdown图片引用
                    const imageName = file.name;
                    const markdownImage = `![${imageName}](${e.target.result})`;
                    
                    // 插入到光标位置
                    const start = markdownInput.selectionStart;
                    const end = markdownInput.selectionEnd;
                    const text = markdownInput.value;
                    markdownInput.value = text.substring(0, start) + markdownImage + text.substring(end);
                    
                    // 更新预览
                    convertMarkdown();
                    updateWordCount();
                };
                reader.readAsDataURL(file);
            }
        }

        // 事件监听
        markdownInput.addEventListener('input', () => {
            convertMarkdown();
            updateWordCount();
        });

        convertBtn.addEventListener('click', convertMarkdown);
        copyBtn.addEventListener('click', copyToClipboard);
        clearBtn.addEventListener('click', clearContent);

        // 图片上传事件
        uploadArea.addEventListener('click', () => {
            imageInput.click();
        });

        uploadArea.addEventListener('dragover', (e) => {
            e.preventDefault();
            uploadArea.style.background = '#e8f4fc';
            uploadArea.style.borderColor = '#2980b9';
        });

        uploadArea.addEventListener('dragleave', () => {
            uploadArea.style.background = '#f8fafc';
            uploadArea.style.borderColor = '#3498db';
        });

        uploadArea.addEventListener('drop', (e) => {
            e.preventDefault();
            uploadArea.style.background = '#f8fafc';
            uploadArea.style.borderColor = '#3498db';
            const files = e.dataTransfer.files;
            handleImageUpload(files);
        });

        imageInput.addEventListener('change', (e) => {
            handleImageUpload(e.target.files);
            // 清空input，允许重复选择相同文件
            e.target.value = '';
        });

        // 初始化
        convertMarkdown();
        updateWordCount();
    </script>
</body>
</html>